﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace S4Store.Models.AfterSaleReport
{
    public class AfterSaleReportServiceAdvisorModel : BaseReportModel
    {
        public Domain.AfterSaleKpi.MonthStandardConfig StandardConfig { get; set; }
        public List<Domain.AfterSaleKpi.MonthStandardConfig> StandardConfigs { get; set; }

        public Domain.AfterSaleKpi.AfterSaleServiceAdvisorMonthConfig MonthConfig { get; set; }

        public List<Domain.AfterSaleKpi.AfterSaleServiceAdvisorMonthTarget> MonthTarget { get; set; }
        public List<Domain.AfterSaleKpi.AfterSaleServiceAdvisorMonthTarget> MonthTargets { get; set; }
        public List<Domain.AfterSaleKpi.AfterSaleServiceAdvisorDayInput> SADayDatas { get; set; }
        public List<Domain.AfterSaleKpi.AfterSaleServiceAdvisorDayInput> SADayData { get; set; }


        public List<Domain.AfterSaleKpi.AfterSaleCustomerServiceDayInput> CSDayDatas { get; set; }

        public List<Domain.AfterSaleKpi.AfterSaleWorkshopManagerDayInput> WMDayDatas { get; set; }
        public List<Domain.AfterSaleKpi.AfterSaleWorkshopManagerMonthConfig> WMMonthConfigs { get; set; }
        public List<Domain.AfterSaleKpi.AfterSaleWorkshopManagerDayInput> WMDayDatasHistory { get; set; }

        public S4Store.Models.Chart.Pie TimeRate { get; set; }


        #region 公共
        /// <summary>
        /// 按指定月份读取ZLSSL
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public Domain.AfterSaleKpi.MonthStandardConfig GetConfig(int year, int month)
        {
            var config = StandardConfigs.Where(o => o.Month.Month == month && o.Month.Year == year).FirstOrDefault();
            if (config == null) return new Domain.AfterSaleKpi.MonthStandardConfig();
            return config;
        }
        #endregion

       

        /// <summary>
        /// 流失客户回归率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetLSKHHGL(int employid,int year, int month)
        {

            var 月初总数 = MonthTarget.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.LGYWHCZS);
            var 本月累计 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.XZLGYWHCS);
            var 重新回厂 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.LSKHCXHCS);
            if (月初总数 + 本月累计 - 重新回厂 == 0) return 0;

            var 客服专员人数 = CSDayDatas.GroupBy(o => o.EmployeeId).Count();
            var 流失客户重新回厂数 = CSDayDatas.Where(o => o.EmployeeId == employid).Sum(o => o.LSKHCXHCS);
            if (客服专员人数 == 0 || 流失客户重新回厂数 == 0) return 0;
            return Math.Round(((decimal)流失客户重新回厂数 / ((decimal)(月初总数 + 本月累计 - 重新回厂) / (decimal)客服专员人数)) * 100, 1, MidpointRounding.AwayFromZero);


        }
        /// <summary>
        /// 流失客户平均回归率  （前台）
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgLSKHHGL(int year, int month)
        {
            if (SADayDatas == null || SADayDatas.Count == 0) return 0;
            var query = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month && o.IsConfirmed);
            var 六月未回厂数 = query.Sum(o => o.XZLGYWHCS);
            var 流失客户重新回厂数 = CSDayDatas.Sum(o => o.LSKHCXHCS);
            if (六月未回厂数 == 0 || 流失客户重新回厂数 == 0) return 0;
            return Math.Round(((decimal)流失客户重新回厂数 / (decimal)六月未回厂数 ) * 100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 流失客户平均回归率  （后台）
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgLSKHHGL_Back(int year, int month)
        {
            if (SADayDatas == null || SADayDatas.Count == 0) return 0;
            var query = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month && o.IsConfirmed);
            var 六月未回厂数 = query.Sum(o => o.XZLGYWHCS);
            var 流失客户重新回厂数 = CSDayDatas.Sum(o => o.LSKHCXHCS);
            if (六月未回厂数 == 0 || 流失客户重新回厂数 == 0) return 0;
            return Math.Round(((decimal)流失客户重新回厂数 / (decimal)六月未回厂数) * 100, 1, MidpointRounding.AwayFromZero);
        }


        /// <summary>
        /// 维   修   客   户   回  访   率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetWXHFL(int employid,int year,int month)
        {
            //公式部分
            //维   修   客   户   回  访   率
            //G5/D5
            //累计维修后回访数/(服务顾问管理数据统计!Z20/C13)
            //累计维修后回访数/((累计完成事故入厂台次+累计完成维修入厂台次)/客户人员总数)
            if (CSDayDatas == null || CSDayDatas.Count() == 0) return 0;
            var 累计维修后回访数 = CSDayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month && o.EmployeeId==employid).Sum(o => o.LJWXHHFS);
            if (累计维修后回访数 == 0) return 0;
            var 客户人员总数 = CSDayDatas.GroupBy(o => o.EmployeeId).Count();
            if (SADayDatas == null || SADayDatas.Count == 0) return 0;
            var 累计入厂台次 = SADayDatas.Sum(o => o.SGRCTC_AccidentToFactory + o.WXRCTC_MaintentceToFactory);
            if (累计入厂台次 == 0) return 0;
            return Math.Round(((decimal)累计维修后回访数 / ((decimal)累计入厂台次 / (decimal)客户人员总数))*100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 维   修   客   户   回  访   率
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgWXHFL(int year, int month)
        {
            if (CSDayDatas == null || CSDayDatas.Count() == 0) return 0;
            var 累计维修后回访数 = CSDayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.LJWXHHFS);
            if (累计维修后回访数 == 0) return 0;
            if (SADayDatas == null || SADayDatas.Count == 0) return 0;
            var 累计入厂台次 = SADayDatas.Sum(o => o.SGRCTC_AccidentToFactory + o.WXRCTC_MaintentceToFactory);
            if (累计入厂台次 == 0) return 0;
            return Math.Round(((decimal)累计维修后回访数 / ((decimal)累计入厂台次)) * 100, 1, MidpointRounding.AwayFromZero);
        }



        /// <summary>
        /// 六   月   未   回   厂   客   户   回  访   率
        /// </summary>
        /// <returns></returns>
        public decimal GetLYWHCL(int employid, int year, int month)
        {
            //公式部分
            //六   月   未   回   厂   客   户   回  访   率
            //六    月   未   回   厂   客   户   回   访   数/(服务顾问管理数据统计!F20/客服专员管理数据统计!C13)
            //六    月   未   回   厂   客   户   回   访   数/((月初总数+本月累计-重新回厂)/客户人员总数)
            if (CSDayDatas == null || CSDayDatas.Count == 0) return 0;
            var 六月未回厂客户回访数 = CSDayDatas.Where(o => o.EmployeeId == employid).Sum(o => o.LYWHCKHHFS);
            if (六月未回厂客户回访数 == 0) return 0;
            var 客户人员总数 = CSDayDatas.GroupBy(o => o.EmployeeId).Count();
            if(客户人员总数==0) return 0;
            var 月初总数 = MonthTarget.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o=>o.LGYWHCZS);
            var 本月累计 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.XZLGYWHCS);
            var 重新回厂 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.LSKHCXHCS);
            if (月初总数 + 本月累计 - 重新回厂 == 0) return 0;
            return Math.Round(((decimal)六月未回厂客户回访数 / ((decimal)(月初总数 + 本月累计 - 重新回厂) / (decimal)客户人员总数))*100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 六   月   未   回   厂   客   户  平均  回  访   率
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgLYWHCL(int year, int month)
        {
            if (CSDayDatas == null || CSDayDatas.Count == 0) return 0;
            var 六月未回厂客户回访数 = CSDayDatas.Sum(o => o.LYWHCKHHFS);
            if (六月未回厂客户回访数 == 0) return 0;
            var 月初总数 = MonthTarget.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.LGYWHCZS);
            var 本月累计 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.XZLGYWHCS);
            var 重新回厂 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.LSKHCXHCS);
            if (月初总数 + 本月累计 - 重新回厂 == 0) return 0;
            return Math.Round(((decimal)六月未回厂客户回访数 / ((decimal)(月初总数 + 本月累计 - 重新回厂))) * 100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 四   月   未   回   厂   客   户   回   访   率
        /// </summary>
        /// <returns></returns>
        public decimal GetSYWHCKHHFL(int employid, int year, int month)
        {
            //公式部分
            //四   月   未   回   厂   客   户   回  访   率
            //四    月   未   回   厂   客   户   回   访   数/(服务顾问管理数据统计!F20/客服专员管理数据统计!C13)
            //四    月   未   回   厂   客   户   回   访   数/((月初总数+本月累计)/客户人员总数)
            if (CSDayDatas == null || CSDayDatas.Count == 0) return 0;
            var 四月未回厂客户回访数 = CSDayDatas.Where(o => o.EmployeeId == employid).Sum(o => o.SYWHCKHHFS);
            if (四月未回厂客户回访数 == 0) return 0;
            var 客户人员总数 = CSDayDatas.GroupBy(o => o.EmployeeId).Count();
            if (客户人员总数 == 0) return 0;
            var 月初总数 = MonthTarget.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SGYWHCZS);
            var 本月累计 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.XZSGYWHCS);
            if (月初总数 + 本月累计 == 0) return 0;
            return Math.Round(((decimal)四月未回厂客户回访数 / ((decimal)(月初总数 + 本月累计) / (decimal)客户人员总数)) * 100, 1, MidpointRounding.AwayFromZero);
        }

        public decimal GetAvgSYWHCKHHFL(int year, int month)
        {
            if (CSDayDatas == null || CSDayDatas.Count == 0) return 0;
            var 四月未回厂客户回访数 = CSDayDatas.Sum(o => o.SYWHCKHHFS);
            if (四月未回厂客户回访数 == 0) return 0;
            var 月初总数 = MonthTarget.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SGYWHCZS);
            var 本月累计 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.XZSGYWHCS);
            if (月初总数 + 本月累计 == 0) return 0;
            return Math.Round(((decimal)四月未回厂客户回访数 / ((decimal)(月初总数 + 本月累计))) * 100, 1, MidpointRounding.AwayFromZero);
        }

        ///本 月 新 增 六 月 未 回 厂 客 户 数
        public int GetBYXZLYWHCKHS(int year,int month)
        {
            var 月初总数 = MonthTarget.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.LGYWHCZS);
            var 本月累计 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.XZLGYWHCS);
            var 重新回厂 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.LSKHCXHCS);
            return 月初总数 + 本月累计 - 重新回厂;

        }

        ///本 月 新 增 四 月 未 回 厂 客 户 数
        public int GetBYXZSYWHCKHS(int year, int month)
        {
            var 月初总数 = MonthTarget.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SGYWHCZS);
            var 本月累计 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.XZSGYWHCS);
            return 月初总数 + 本月累计;
        }

        /// <summary>
        /// 一次修复率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetYCXHL(int employid, int year, int month)
        {
            //=SUM((F5-Q5)/F5)
            //(本月累计入厂台次 - 交车后回厂返修总数)/本月累计入厂台次
            var query = WMDayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month);
            var 本月累计入厂台次 = query.Sum(o=>o.LYLJRCTC);
            if (本月累计入厂台次 == 0) return 0;
            var 交车后回厂返修总数 = query.Sum(o => o.JCHHCFXZS);
            return Math.Round((((decimal)本月累计入厂台次 - (decimal)交车后回厂返修总数) / (decimal)本月累计入厂台次)*100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 一次修复平均率GetAvgHistoryYCXHL
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgYCXHL(int year, int month)
        {
            //=SUM((F5-Q5)/F5)
            //(本月累计入厂台次 - 交车后回厂返修总数)/本月累计入厂台次
            var query = WMDayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month);
            var 本月累计入厂台次 = query.Sum(o => o.LYLJRCTC);
            if (本月累计入厂台次 == 0) return 0;
            var 交车后回厂返修总数 = query.Sum(o => o.JCHHCFXZS);
            return Math.Round((((decimal)本月累计入厂台次 - (decimal)交车后回厂返修总数) / (decimal)本月累计入厂台次) * 100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 部门工位效益
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgGWXY(int year, int month)
        {
            //=SUM((F5-Q5)/F5)
            //(本月累计入厂台次 - 交车后回厂返修总数)/本月累计入厂台次
            var config = WMMonthConfigs.Where(o =>o.AddTime.Year == year && o.AddTime.Month == month);
            if(config==null) return 0;

            var query = WMDayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month);
            var 维修产值 = query.Sum(o => o.BYLJWXCZ);
            var 工位总数 = config.Sum(o => o.BMGWZS);

            if (维修产值 == 0 || 工位总数==0) return 0;
            return Math.Round((维修产值 / (decimal)工位总数), 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 部门工位效益
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetGWXY(int employid,int year, int month)
        {
            //=SUM((F5-Q5)/F5)
            //(本月累计入厂台次 - 交车后回厂返修总数)/本月累计入厂台次
            var config = WMMonthConfigs.Where(o => o.EmployeeId==employid && o.AddTime.Year == year && o.AddTime.Month == month);
            var query = WMDayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month);

            var 维修产值 = query.Sum(o => o.BYLJWXCZ);
            var 工位总数 = config.Sum(o => o.BMGWZS);

            if (维修产值 == 0 || 工位总数 == 0) return 0;
            return Math.Round((维修产值 / (decimal)工位总数), 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 一次修复平均率GetAvgHistoryYCXHL
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgHistoryYCXHL(int year, int month)
        {
            //=SUM((F5-Q5)/F5)
            //(本月累计入厂台次 - 交车后回厂返修总数)/本月累计入厂台次
            var query = WMDayDatasHistory.Where(o => o.AddTime.Year == year && o.AddTime.Month == month);
            var 本月累计入厂台次 = query.Sum(o => o.LYLJRCTC);
            if (本月累计入厂台次 == 0) return 0;
            var 交车后回厂返修总数 = query.Sum(o => o.JCHHCFXZS);
            return Math.Round((((decimal)本月累计入厂台次 - (decimal)交车后回厂返修总数) / (decimal)本月累计入厂台次) * 100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 设备完好率
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetSBWHL(int employid,int year, int month)
        {
            //=SUM(K5/D5)
            //功   能  完   好   设  备   工   具  完  好   数/部    门   设   备   工   具   总   数
            //功   能  完   好   设  备   工   具  完  好   数 （取当天）
            var query = WMMonthConfigs.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month).FirstOrDefault();
            if (query == null) return 0;
            var 部门设备工具总数 = query.BMGJZS;
            if (部门设备工具总数 == 0) return 0;
            var query1 = WMDayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month && o.AddTime.Day == new DateTime(year, month,1).LastOrNowDay()).FirstOrDefault();
            if (query1 == null) return 0;
            var 功能完好设备工具完好数 = query1.GNWHSBGJZS;
            return Math.Round(((decimal)功能完好设备工具完好数 / (decimal)部门设备工具总数) * 100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 设备完好平均率
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgSBWHL(int year, int month)
        {
            //=SUM(K5/D5)
            //功   能  完   好   设  备   工   具  完  好   数/部    门   设   备   工   具   总   数
            //功   能  完   好   设  备   工   具  完  好   数 （取当天）
            var query = WMMonthConfigs.Where(o => o.AddTime.Year == year && o.AddTime.Month == month);
            var 部门设备工具总数 = query.Sum(o=>o.BMGJZS);
            if (部门设备工具总数 == 0) return 0;
            var query1 = WMDayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month && o.AddTime.Day == new DateTime(year, month, 1).LastOrNowDay());
            var 功能完好设备工具完好数 = query1.Sum(o=>o.GNWHSBGJZS);
            return Math.Round(((decimal)功能完好设备工具完好数 / (decimal)部门设备工具总数) * 100, 1, MidpointRounding.AwayFromZero);
        }


        /// <summary>
        /// 工单报废率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetGDBFL(int employid, int year, int month)
        {
            //=SUM(L5/E5)
            //无   效   工   单   数   量/本   月   工   单   总   数
            var query = WMDayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month);
            var 无效工单数量 = query.Sum(o=>o.WXGDSL);
            var 本月工单总数 = query.Sum(o => o.BYGDZS);
            if (无效工单数量 == 0 || 本月工单总数 == 0) return 0;
            return Math.Round(((decimal)无效工单数量 / (decimal)本月工单总数) * 100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 工单报废平均率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgGDBFL(int year, int month)
        {
            //=SUM(L5/E5)
            //无   效   工   单   数   量/本   月   工   单   总   数
            var query = WMDayDatas.Where(o=>o.AddTime.Year == year && o.AddTime.Month == month);
            var 无效工单数量 = query.Sum(o => o.WXGDSL);
            var 本月工单总数 = query.Sum(o => o.BYGDZS);
            if (无效工单数量 == 0 || 本月工单总数 == 0) return 0;
            return Math.Round(((decimal)无效工单数量 / (decimal)本月工单总数) * 100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 准时交车率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetZSJCL(int employid, int year, int month)
        {
            //(预计时间前交车总数/本月已交车总数
            var query = WMDayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month);
            var 预计时间前交车总数 = query.Sum(o => o.YJSJQJCZS);
            var 本月已交车总数 = query.Sum(o => o.BYYJCZS);
            if (预计时间前交车总数 == 0 || 本月已交车总数 == 0) return 0;
            return Math.Round((((decimal)预计时间前交车总数) / (decimal)本月已交车总数) * 100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 准时交车率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetSAZSJCL(int employid, int year, int month)
        {
            //准时交车客户数/累计完成入厂台次
            if (SADayDatas == null) return 0;
            var SA = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month && o.EmployeeId == employid);
            var 累计完成入厂台次 = SA.Sum(o => o.WXRCTC_MaintentceToFactory + o.SGRCTC_AccidentToFactory);
            var 准时交车客户数 = SA.Sum(o => o.ZSJCKHS);
            
            if (累计完成入厂台次 == 0 || 准时交车客户数 == 0) return 0;
            return Math.Round((((decimal)准时交车客户数) / (decimal)累计完成入厂台次) * 100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 平均准时交车率
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgZSJCL(int year, int month)
        {
            var query = WMDayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month);
            var 预计时间前交车总数 = query.Sum(o => o.YJSJQJCZS);
            var 本月已交车总数 = query.Sum(o => o.BYYJCZS);
            if (预计时间前交车总数 == 0 || 本月已交车总数 == 0) return 0;
            return Math.Round((((decimal)预计时间前交车总数) / (decimal)本月已交车总数) * 100, 1, MidpointRounding.AwayFromZero);
        }

        #region 招徕实施率
        /// <summary>
        /// 招徕实施率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetZLSSL(int employid, int year, int month)
        {
            //=SUM(AF6/J6)
            //成功实施电话招徕客户数/本月招徕回厂目标数
            var 成功实施电话招徕客户数 = SADayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.DHZLKHS_InviteByTelNum);
            var 本月招徕回厂目标数 = MonthTargets.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.BYYZHCMBS_ReturnFactoryTarget);
            if (本月招徕回厂目标数 == 0 || 成功实施电话招徕客户数 == 0) return 0;
            return Math.Round((((decimal)成功实施电话招徕客户数) / (decimal)本月招徕回厂目标数) * 100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 招徕实施率差异
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetZLSSLCY(int employid, int year, int month)
        {
            var zlssl = GetZLSSL(employid, year, month);
            var config = StandardConfigs.Where(o => o.Month.Month == month && o.Month.Year == year).FirstOrDefault();
            if (config == null) return zlssl;
            return (zlssl - config.招徕实施率目标);
        }

        /// <summary>
        /// 平均招徕实施率差异
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgZLSSLCY(int year, int month)
        {
            var zlssl = GetAvgZLSSL(year, month);
            var config = StandardConfigs.Where(o => o.Month.Month == month && o.Month.Year == year).FirstOrDefault();
            if (config == null) return zlssl;
            return (zlssl - config.招徕实施率目标);
        }



        /// <summary>
        /// 平均招徕实施率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgZLSSL(int year, int month)
        {
            //=SUM(AF6/J6)
            //成功实施电话招徕客户数/本月招徕回厂目标数
            var 成功实施电话招徕客户数 = SADayDatas.Where(o=>o.AddTime.Year==year && o.AddTime.Month==month).Sum(o => o.DHZLKHS_InviteByTelNum);
            var 本月招徕回厂目标数 = MonthTargets.Where(o=>o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.BYYZHCMBS_ReturnFactoryTarget);
            if (本月招徕回厂目标数 == 0 || 成功实施电话招徕客户数 == 0) return 0;
            return Math.Round((((decimal)成功实施电话招徕客户数) / (decimal)本月招徕回厂目标数) * 100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 招徕实施率目标
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetConfigZLSSL(int year, int month)
        {
            var config = StandardConfigs.Where(o => o.Month.Month == month && o.Month.Year == year).FirstOrDefault();
            if (config == null) return 0;
            return config.招徕实施率目标;
        }

        #endregion

        #region 预约成功率
        /// <summary>
        /// 预约成功率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetYYCGL(int employid, int year, int month)
        {
            //=SUM(AH6/Z6)
            //累计实现预约回厂数/(累计事故车入厂台次+累计维修厂入厂台次)
            var 累计实现预约回厂数 = SADayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SXYYHCS);
            var 入厂台次 = SADayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SGRCTC_AccidentToFactory+o.WXRCTC_MaintentceToFactory);
            if (入厂台次 == 0 || 累计实现预约回厂数 == 0) return 0;
            return Math.Round((((decimal)累计实现预约回厂数) / (decimal)入厂台次) * 100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 平均成功预约率
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgYYCGL(int year, int month)
        {
            var 累计实现预约回厂数 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SXYYHCS);
            var 入厂台次 = SADayDatas.Where(o =>  o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SGRCTC_AccidentToFactory + o.WXRCTC_MaintentceToFactory);
            if (入厂台次 == 0 || 累计实现预约回厂数 == 0) return 0;
            return Math.Round((((decimal)累计实现预约回厂数) / (decimal)入厂台次) * 100, 1, MidpointRounding.AwayFromZero);
        }

        #endregion

        #region 失约率
        /// <summary>
        /// 失约率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetSYL(int employid, int year, int month)
        {
            //=SUM((AG6-AH6)/AG6)
            //(电话成功预约回厂数-累计实现预约回厂数)/电话成功预约回厂数
            var 累计实现预约回厂数 = SADayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SXYYHCS);
            var 电话成功预约回厂数 = SADayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.DHCGYYHCS);
            if (电话成功预约回厂数 == 0) return 0;
            return Math.Round((((decimal)电话成功预约回厂数 - (decimal)累计实现预约回厂数) / (decimal)电话成功预约回厂数) * 100, 1, MidpointRounding.AwayFromZero);

        }

        /// <summary>
        /// 平均失约率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgSYL(int year, int month)
        {
            //=SUM((AG6-AH6)/AG6)
            //(电话成功预约回厂数-累计实现预约回厂数)/电话成功预约回厂数
            var 累计实现预约回厂数 = SADayDatas.Where(o=> o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SXYYHCS);
            var 电话成功预约回厂数 = SADayDatas.Where(o=> o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.DHCGYYHCS);
            if (电话成功预约回厂数 == 0) return 0;
            return Math.Round((((decimal)电话成功预约回厂数 - (decimal)累计实现预约回厂数) / (decimal)电话成功预约回厂数) * 100, 1, MidpointRounding.AwayFromZero);

        }

        #endregion

        #region 隐形流失率
        /// <summary>
        /// 隐形流失率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetYXLSL(int employid, int year, int month)
        {
            //四个月未回厂客户总数/分   管   保   有   客   户   总   数
            var MT = MonthTargets.Where(o => o.AddTime.Year == year && o.AddTime.Month == month && o.EmployeeId==employid);
            var SAD = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month && o.EmployeeId==employid);

            int 六个月未来店客户数 = MT.Sum(o => o.LGYWHCZS) + SAD.Sum(o => o.XZLGYWHCS - o.LSKHCXHCS);

            var 四个月未回厂客户数 = MT.Sum(o => o.SGYWHCZS) + SAD.Sum(o => o.XZSGYWHCS);

            var 分管的保有客户数 = MT.Sum(o => o.SYMFGKHZS_LastMonthManageCustomerNum) + SAD.Sum(o => o.BYAKZCKKHS_ACard2CCard) - 六个月未来店客户数;
            return 分管的保有客户数 == 0 ? 0 : Math.Round(((decimal)四个月未回厂客户数 / (decimal)分管的保有客户数) * 100, 2, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 平均隐形流失率
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgYXLSL(int year, int month)
        {
            //四个月未回厂客户总数/分   管   保   有   客   户   总   数
            var MT = MonthTargets.Where(o => o.AddTime.Year == year && o.AddTime.Month == month);
            var SAD = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month);

            int 六个月未来店客户数 = MT.Sum(o => o.LGYWHCZS) + SAD.Sum(o => o.XZLGYWHCS - o.LSKHCXHCS);

            var 四个月未回厂客户数 = MT.Sum(o => o.SGYWHCZS) + SAD.Sum(o => o.XZSGYWHCS);

            var 分管的保有客户数 = MT.Sum(o => o.SYMFGKHZS_LastMonthManageCustomerNum) + SAD.Sum(o => o.BYAKZCKKHS_ACard2CCard) - 六个月未来店客户数;
            return 分管的保有客户数 == 0 ? 0 : Math.Round(((decimal)四个月未回厂客户数 / (decimal)分管的保有客户数) * 100, 2, MidpointRounding.AwayFromZero);
        }

        #endregion

        #region 事实流失率

        /// <summary>
        /// 分   管   保   有   客   户   总   数
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetFGBYKHZS(int employid , int year, int month)
        {
            //客户流失率与目标流失率的差值
            //6个月未回厂数/分保管客户总数
            if (MonthTargets == null || SADayDatas == null) return 0;
            var MT = MonthTargets.Where(o => o.AddTime.Year == year && o.AddTime.Month == month && o.EmployeeId==employid);
            var SAD = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month && o.EmployeeId==employid);

            int 六个月未来店客户数 = MT.Sum(o => o.LGYWHCZS) + SAD.Sum(o => o.XZLGYWHCS - o.LSKHCXHCS);
            var 分管的保有客户数 = MT.Sum(o => o.SYMFGKHZS_LastMonthManageCustomerNum) + SAD.Sum(o => o.BYAKZCKKHS_ACard2CCard) - 六个月未来店客户数;
            return 分管的保有客户数;
        }

        public int Get本月目标预约入厂台次(int employid, int year, int month)
        {
            return 0;
        }


        /// <summary>
        /// 事实客户平均流失率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgSSKHLSL(int year, int month)
        {
            //客户流失率与目标流失率的差值
            //6个月未回厂数/分保管客户总数
            if (MonthTargets == null || SADayDatas == null) return 0;
            var MT = MonthTargets.Where(o => o.AddTime.Year == year && o.AddTime.Month == month);
            var SAD = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month);

            int 六个月未来店客户数 = MT.Sum(o => o.LGYWHCZS) + SAD.Sum(o => o.XZLGYWHCS - o.LSKHCXHCS);
            var 分管的保有客户数 = MT.Sum(o => o.SYMFGKHZS_LastMonthManageCustomerNum) + SAD.Sum(o => o.BYAKZCKKHS_ACard2CCard) - 六个月未来店客户数;
            return 分管的保有客户数 == 0 ? 0 : Math.Round(((decimal)六个月未来店客户数 / (decimal)分管的保有客户数) * 100, 2, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 事实客户流失率差异
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal z_SSKHLSL_CY(int year, int month)
        {
            var config = StandardConfigs.Where(o => o.Month.Year == year && o.Month.Month == month).FirstOrDefault();
            if (config == null) config = new Domain.AfterSaleKpi.MonthStandardConfig();
            return Math.Round(config.事实流失率目标 - z_SSKHLSL(year, month), 2, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 事实客户流失率
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal z_SSKHLSL(int year, int month)
        {
            //客户流失率与目标流失率的差值
            //6个月未回厂数/分保管客户总数
            if (MonthTargets == null || SADayDatas == null) return 0;
            var MT = MonthTargets.Where(o => o.AddTime.Year == year && o.AddTime.Month == month);
            var SAD = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month);

            int 六个月未来店客户数 = MT.Sum(o => o.LGYWHCZS) + SAD.Sum(o => o.XZLGYWHCS - o.LSKHCXHCS);
            var 分管的保有客户数 = MT.Sum(o => o.SYMFGKHZS_LastMonthManageCustomerNum) + SAD.Sum(o => o.BYAKZCKKHS_ACard2CCard) - 六个月未来店客户数;
            return 分管的保有客户数 == 0 ? 0 : Math.Round(((decimal)六个月未来店客户数 / (decimal)分管的保有客户数) * 100, 2, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 事实客户流失率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetSSKHLSL(int employid, int year, int month)
        {
            if (MonthTargets == null || SADayDatas == null) return 0;

            var MT = MonthTargets.Where(o => o.AddTime.Year == year && o.AddTime.Month == month && o.EmployeeId == employid);
            var SAD = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month && o.EmployeeId == employid);

            int 六个月未来店客户数 = MT.Sum(o => o.LGYWHCZS) + SAD.Sum(o => o.XZLGYWHCS - o.LSKHCXHCS);
            var 分管的保有客户数 = MT.Sum(o => o.SYMFGKHZS_LastMonthManageCustomerNum) + SAD.Sum(o => o.BYAKZCKKHS_ACard2CCard) - 六个月未来店客户数;
            return 分管的保有客户数 == 0 ? 0 : Math.Round(((decimal)六个月未来店客户数 / (decimal)分管的保有客户数) * 100, 2, MidpointRounding.AwayFromZero);
        }

        #endregion


        /// <summary>
        /// 
        /// </summary>
        public decimal _5K保养完成率(int sellerid, int year, int month)
        {
            var _5K目标保养数 = MonthTarget.Where(o => o.EmployeeId == sellerid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.BYYSSWKBYS_5KMaintenceTarget);
            var _5K实际保养数 = SADayDatas.Where(o => o.EmployeeId == sellerid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SSWQBYS_5KMaintenceNum);
            if (_5K目标保养数 == 0 || _5K实际保养数 == 0) return 0;
            return Math.Round((decimal)_5K实际保养数 / (decimal)_5K目标保养数 * 100, 1, MidpointRounding.AwayFromZero);
        }

        public decimal _10K保养完成率(int sellerid, int year, int month)
        {
            var _10K目标保养数 = MonthTarget.Where(o => o.EmployeeId == sellerid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.BYYSSSQBYS_10KMaintenceTarget);
            var _10K实际保养数 = SADayDatas.Where(o => o.EmployeeId == sellerid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SSSQBYS_10KMaintenceNum);
            if (_10K目标保养数 == 0 || _10K实际保养数 == 0) return 0;
            return Math.Round((decimal)_10K实际保养数 / (decimal)_10K目标保养数 * 100, 1, MidpointRounding.AwayFromZero);
        }

        public decimal 维修入场台次完成率(int sellerid, int year, int month)
        {
            var 目标维修入场台次 = MonthTarget.Where(o => o.EmployeeId == sellerid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.BYWXRCTCMB_MaintenceCarToFactoryTarget);
            var 实际维修入场台次 = SADayDatas.Where(o => o.EmployeeId == sellerid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.WXRCTC_MaintentceToFactory);
            if (目标维修入场台次 == 0 || 实际维修入场台次 == 0) return 0;
            return Math.Round((decimal)实际维修入场台次 / (decimal)目标维修入场台次 * 100, 1, MidpointRounding.AwayFromZero);
        }


        public decimal 首次续保完成率(int sellerid, int year, int month)
        {
            var 首次续保完成目标 = MonthTarget.Where(o => o.EmployeeId == sellerid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SCXBTCMB_FirstRenewTarget);
            var 实际续保完成目标 = SADayDatas.Where(o => o.EmployeeId == sellerid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SCXBSJWCTC);
            if (首次续保完成目标 == 0 || 实际续保完成目标 == 0) return 0;
            return Math.Round((decimal)实际续保完成目标 / (decimal)首次续保完成目标 * 100, 1, MidpointRounding.AwayFromZero);
        }

        public decimal 二次续保完成率(int sellerid, int year, int month)
        {
            var 二次续保完成目标 = MonthTarget.Where(o => o.EmployeeId == sellerid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.ECXBTCMB_SecondRenewTarget);
            var 实际二次续保完成 = SADayDatas.Where(o => o.EmployeeId == sellerid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.ECXBSJWCTC);
            if (二次续保完成目标 == 0 || 实际二次续保完成 == 0) return 0;
            return Math.Round((decimal)实际二次续保完成 / (decimal)二次续保完成目标 * 100, 1, MidpointRounding.AwayFromZero);
        }

        public decimal 事故车台次完成率(int sellerid, int year, int month)
        {
            var 事故车台次完成目标 = MonthTarget.Where(o => o.EmployeeId == sellerid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.BYSGCRCTCMB_AccidentCarToFactoryTarget);
            var 实际事故车台次完成 = SADayDatas.Where(o => o.EmployeeId == sellerid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.SGRCTC_AccidentToFactory);
            if (事故车台次完成目标 == 0 || 实际事故车台次完成 == 0) return 0;
            return Math.Round((decimal)实际事故车台次完成 / (decimal)事故车台次完成目标 * 100, 1, MidpointRounding.AwayFromZero);
        }

        public decimal 常态维修产值(int sellerid, int year, int month)
        {
            return  SADayDatas.Where(o => o.EmployeeId == sellerid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.WXCZ_MaintenceValue);
        }

        /// <summary>
        /// 平均用品销售完成率
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgJPXSL(int year, int month)
        {
            var 用品销售目标 = MonthTarget.Where( o=> o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.JPMBXSE_CompetitiveSaleTarget);
            var 实际用品销售 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.LJJPXSE);
            if (用品销售目标 == 0 || 实际用品销售 == 0) return 0;
            return 实际用品销售 / 用品销售目标;
        }

        /// <summary>
        /// 养护产品完成率
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgYHCPXSWCL(int year, int month)
        {
            var 养护产品销售目标 = MonthTarget.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.YHCPMBXSE_MaintenceSaleTarget);
            var 实际养护产品销售 = SADayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.LJYHCPXSE);
            if (养护产品销售目标 == 0 || 实际养护产品销售 == 0) return 0;
            return 实际养护产品销售 / 养护产品销售目标;
        }


        /// <summary>
        /// 平均人均工位数
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgRJGWS(int year, int month)
        {
            //=SUM(C5/J5)
            //部   门   机   师   总   数/部   门   工   位   总   数
            if (WMMonthConfigs == null) return 0;
            var M = WMMonthConfigs.Where(o => o.AddTime.Year == year && o.AddTime.Month == month);
            var 部门机师总数 = M.Sum(o => o.BMJSZS);
            var 部门工位总数 = M.Sum(o => o.BMGWZS);
            if (部门机师总数 == 0 || 部门工位总数 == 0) return 0;
            return Math.Round((decimal)部门机师总数 / (decimal)部门工位总数, 2, MidpointRounding.AwayFromZero);
        }

        public decimal 工位周转率(int employid, int year, int month)
        {
            //SUM(F5/(M3*J5))
            //本    月     累     计     入     厂     台     次/(已执行天数*部   门   工   位   总   数)
            var 本月累计入厂台次 = WMDayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.LYLJRCTC);
            var 已执行天数 = new DateTime(year, month,1).LastOrNowDay();

            var 部门工位总数 = WMMonthConfigs.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.BMGWZS);
            if (部门工位总数 == 0 || 已执行天数 == 0 || 本月累计入厂台次 == 0) return 0;
            return Math.Round((decimal)本月累计入厂台次 / ((decimal)已执行天数 * (decimal)部门工位总数),2,MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 工位周转率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetGWZZL(int employid, int year, int month)
        {
            //SUM(F5/(M3*J5))
            //本    月     累     计     入     厂     台     次/(已执行天数*部   门   工   位   总   数)
            var 本月累计入厂台次 = WMDayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.LYLJRCTC);
            var 已执行天数 = new DateTime(year, month, 1).LastOrNowDay();

            var 部门工位总数 = WMMonthConfigs.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.BMGWZS);
            if (部门工位总数 == 0 || 已执行天数 == 0 || 本月累计入厂台次 == 0) return 0;
            return Math.Round((decimal)本月累计入厂台次 / ((decimal)已执行天数 * (decimal)部门工位总数), 2, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 平均工位周转率
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgGWZZL(int year, int month)
        {
            //SUM(F5/(M3*J5))
            //本    月     累     计     入     厂     台     次/(已执行天数*部   门   工   位   总   数)
            if (WMDayDatas == null || WMMonthConfigs == null) return 0;
            var 本月累计入厂台次 = WMDayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.LYLJRCTC);
            var 已执行天数 = new DateTime(year, month, 1).LastOrNowDay();

            var 部门工位总数 = WMMonthConfigs.Where(o =>  o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.BMGWZS);
            if (部门工位总数 == 0 || 已执行天数 == 0 || 本月累计入厂台次 == 0) return 0;
            return Math.Round((decimal)本月累计入厂台次 / ((decimal)已执行天数 * (decimal)部门工位总数), 2, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 工时效率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetGSXL(int employid, int year, int month)
        { 
            if (WMDayDatas == null) return 0;
            var D = WMDayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month);
            return D.Sum(o => o.BMSJGSLJZS) == 0 ? 0 : Math.Round(((decimal)D.Sum(o => o.BMDEGSLJZS) / (decimal)D.Sum(o => o.BMSJGSLJZS)) * 100, 1, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 平均工时效率
        /// </summary>
        /// <param name="employid"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        public decimal GetAvgGSXL(int year, int month)
        {
            if (WMDayDatas == null) return 0;
            var D = WMDayDatas.Where(o => o.AddTime.Year == year && o.AddTime.Month == month);
            return D.Sum(o => o.BMSJGSLJZS) == 0 ? 0 : Math.Round(((decimal)D.Sum(o => o.BMDEGSLJZS) / (decimal)D.Sum(o => o.BMSJGSLJZS)) * 100, 1, MidpointRounding.AwayFromZero);
        }



        public decimal 生产利用率(int employid, int year, int month)
        {
            //技   工   实   际   作   业   时   间   总   和/技   工   出   勤   时   间   总   和
            var 技工实际作业时间总和 = WMDayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.JGSJZYSJZH);

            var 技工出勤时间总和 = WMDayDatas.Where(o => o.EmployeeId == employid && o.AddTime.Year == year && o.AddTime.Month == month).Sum(o => o.JGCQSJZH);
            if (技工出勤时间总和 == 0 || 技工实际作业时间总和 == 0) return 0;

            return (decimal)技工实际作业时间总和 / (decimal)技工出勤时间总和;

        }


        /// <summary>
        ///  目标预约入厂台次
        /// </summary>
        /// <param name="?"></param>
        /// <param name="?"></param>
        /// <param name="?"></param>
        /// <returns></returns>
        public decimal GetBYMBRCTC(int employid,int  year,int month)
        {
            //目标入厂台次*成功预约目标
            if (MonthTargets == null || StandardConfigs == null) return 0;
            var MT = MonthTargets.Where(o => o.AddTime.Year == year && o.AddTime.Month == month && o.EmployeeId==employid);
            var config = StandardConfigs.Where(o => o.Month.Year == year && o.Month.Month == month).FirstOrDefault();

            if(config==null) return 0;

            var 目标入厂台次 = MT.Sum(o => o.BYSGCRCTCMB_AccidentCarToFactoryTarget + o.BYWXRCTCMB_MaintenceCarToFactoryTarget + o.BYYSSWKBYS_5KMaintenceTarget + o.BYYSSSQBYS_10KMaintenceTarget);
            var 成功预约目标 = config.预约成功率目标;

            return Math.Round(目标入厂台次 * 成功预约目标/100,0, MidpointRounding.AwayFromZero);
        }
        
        
    }
}
